import os
import sys

# 自动将项目根目录加入 sys.path（需在导入 core.* 模块之前执行）
CURRENT_DIR = os.path.dirname(os.path.abspath(__file__))
PROJECT_ROOT = os.path.abspath(os.path.join(CURRENT_DIR, "../../../"))
if PROJECT_ROOT not in sys.path:
    sys.path.insert(0, PROJECT_ROOT)

from fastapi import FastAPI, Request, HTTPException
from fastapi.responses import JSONResponse
from pydantic import BaseModel
from typing import Optional
from core.server.fastInterface import generate_test_case, list_methods
from core.testAgent.HumanAssistance import get_human_assistance_manager
from core.testAgent.ProgressTracker import progress_tracker
import uvicorn

DEFAULT_NEO4J_URL = os.getenv("NEO4J_URL", "bolt://localhost:7687")
DEFAULT_NEO4J_USER = os.getenv("NEO4J_USER", "neo4j")
DEFAULT_NEO4J_PASSWORD = os.getenv("NEO4J_PASSWORD", "123456")


app = FastAPI()

class GenerateRequest(BaseModel):
    methodId: int
    url: str = DEFAULT_NEO4J_URL
    username: str = DEFAULT_NEO4J_USER
    password: str = DEFAULT_NEO4J_PASSWORD
    limit: int = 100
    jobId: Optional[str] = None
    allowHumanAssistance: bool = True
    projectPath: Optional[str] = None

class AssistanceReply(BaseModel):
    requestId: str
    content: str

@app.get("/health")
def health():
    return {"status": "ok"}

@app.get("/listMethods")
async def list_methods_endpoint(
    limit: int = 200,
    offset: int = 0,
    focalOnly: bool = True,
    url: str = DEFAULT_NEO4J_URL,
    username: str = DEFAULT_NEO4J_USER,
    password: str = DEFAULT_NEO4J_PASSWORD,
):
    try:
        methods = list_methods(
            url=url,
            username=username,
            password=password,
            limit=limit,
            offset=offset,
            focal_only=focalOnly,
        )
        return {"result": "Success", "methods": methods}
    except Exception as exc:
        print(f"[listMethods] Failed to load methods: {exc}")
        return {"result": "Failed", "message": str(exc), "methods": []}

@app.post("/generateTest")
async def generate_test(req: GenerateRequest):
    try:
        return generate_test_case(
            req.methodId,
            req.url,
            req.username,
            req.password,
            req.limit,
            req.jobId,
            req.allowHumanAssistance,
            req.projectPath
        )
    except Exception as exc:
        print(f"[generateTest] Failed to generate test: {exc}")
        return JSONResponse(
            status_code=500,
            content={"result": "Failed", "message": str(exc)}
        )


@app.get("/progress/{job_id}")
async def get_progress(job_id: str, after: int = 0):
    return progress_tracker.get_events(job_id, after_seq=after)

@app.get("/config")
async def get_config():
    return {
        "configJson": {
            "backend": "TestAgent",
            "model": "PlannerGraph",
            "db": "Neo4j",
            "version": "1.0"
        }
    }

@app.post("/feedback")
async def send_feedback(request: Request):
    payload = await request.json()
    print(f"[Feedback] {payload}")
    return {"status": "ok"}

@app.get("/assistance/requests")
async def list_assistance_requests():
    manager = get_human_assistance_manager()
    return {"result": "Success", "requests": manager.list_pending_requests()}

@app.post("/assistance/respond")
async def respond_to_assistance(body: AssistanceReply):
    manager = get_human_assistance_manager()
    try:
        data = manager.submit_response(body.requestId, body.content)
        return {"result": "Success", "data": data}
    except ValueError as exc:
        raise HTTPException(status_code=404, detail=str(exc))

if __name__ == "__main__":
    uvicorn.run(app, host="127.0.0.1", port=8848)
